const errorTypes = require('../constants/error-types');
const service = require('../service/user.service');
const AuthService = require('../service/auth.service');
const md5password = require('../utils/password-handle')
const jwt = require('jsonwebtoken');
const { PUBLIC_KEY } = require('../app/config');
const verifyLogin = async (ctx, next) => {
  // 1、获取用户名和密码
  const { name, password } = ctx.request.body

  // 2、判断是否为空
  if (!name || !password) {
    const error = new Error(errorTypes.NAME_OR_PASSWORD_IS_REQUIRED);
    return ctx.app.emit('error', error, ctx);
  }
  // 3、判断是否存在
  const result = await service.getUserByName(name);
  const user = result[0]
  if (!user) {
    const error = new Error(errorTypes.USER_DOES_NOT_EXISTS);
    // 发射一个错误信息
    // 在 app文件夹下新建 一个 error-handle.js
    return ctx.app.emit('error', error, ctx);
  }
  // 4、判断密码是否正确(加密后才能判断)
  // 数据库存储的就是加密的 密码
  if (md5password(password) !== user.password) {
    const error = new Error(errorTypes.PASSWORD_IS_INCORRENT)
    // 发射一个错误信息
    // 在 app文件夹下新建 一个 error-handle.js
    return ctx.app.emit('error', error, ctx);
  }

  // 如果上述步骤都正确
  ctx.user = user
  await next()
}

// 验证用户是否授权了  授权是否过期了
const verifyAuth = async (ctx, next) => {
  console.log('验证授权的 middleware~~~');
  const authorization = ctx.headers.authorization;
  console.log(authorization);
  if (!authorization) {
    const error = new Error(errorTypes.UNAUTHORIZATION);
    return ctx.app.emit('error', error, ctx);
  }
  const token = authorization.replace("Bearer ", "");

  // JWT 验证失败，会直接抛出异常的 可以用 try catch 捕获
  try {
    // 验证 token  
    // 第一个参数 token
    // 第二个颁发的签名
    // 第三个参数 设置其他参数
    const result = jwt.verify(token, PUBLIC_KEY, {
      // 设置 验证方式，是一个数组
      algorithms: ["RS256"]
    });
    ctx.user = result;
    await next();
  } catch (err) {
    console.log('验证 token 是否有效', err);
    const error = new Error(errorTypes.UNAUTHORIZATION);
    ctx.app.emit('error', error, ctx);
  }
}

// 验证 修改  是否具备修改动态的资格
// const verifyPermission = async (ctx, next) => {
//   console.log('验证权限的middleware~~~');
//   // 根据传过来的，要 修改 某个文章的 id ，

//   const { momentId } = ctx.params
//   const { id } = ctx.user
//   try {
//     // 查询是否具备权限
//     const isPeermission = await AuthService.checkMoment(momentId, id)
//     console.log('isPeermission  ', isPeermission);
//     if (isPeermission === false) {
//       console.log('走里面了？？？');
//       throw new Error()
//     }
//     await next()
//   } catch (err) {
//     console.log(err, '什么操作？？？');
//     const error = new Error(errorTypes.UNPERMISSION);
//     return ctx.app.emit('error', error, ctx);
//   }
// 验证 是否有  修改 评论的权限

/**
 * 1.很多的内容都需要验证权限: 修改/删除动态, 修改/删除评论
 * 2.接口: 业务接口系统/后端管理系统
 *  一对一: user -> role
 *  多对多: role -> menu(删除动态/修改动态)
 */
const verifyPermission = async (ctx, next) => {
  console.log("验证权限的middleware~");

  // 1.获取参数 { commentId: '1' }
  const [resourceKey] = Object.keys(ctx.params);
  const tableName = resourceKey.replace('Id', '');
  const resourceId = ctx.params[resourceKey];
  const { id } = ctx.user;

  // 2.查询是否具备权限
  try {
    const isPermission = await authService.checkResource(tableName, resourceId, id);
    if (!isPermission) throw new Error();
    await next();
  } catch (err) {
    const error = new Error(errorTypes.UNPERMISSION);
    return ctx.app.emit('error', error, ctx);
  }
}


module.exports = {
  verifyLogin,
  verifyAuth,
  verifyPermission
}